package com.bipbip.controlador;

import java.util.Iterator;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;

import com.bipbip.modelo.MarcaVehiculo;
import com.bipbip.modelo.ModeloVehiculo;
import com.bipbip.modelo.NotificacionStandard;
import com.bipbip.modelo.Producto;
import com.bipbip.modelo.Publicacion;
import com.bipbip.modelo.Suscripcion;
import com.bipbip.modelo.Usuario;
import com.bipbip.service.EmpresaService;
import com.bipbip.service.MarcaService;
import com.bipbip.service.ModeloService;
import com.bipbip.service.NotificacionesFactory;
import com.bipbip.service.NotificacionesService;
import com.bipbip.service.PublicacionService;
import com.bipbip.service.SuscripcionService;
import com.bipbip.service.UsuarioService;
import com.bipbip.service.VehiculoService;

@Controller
@RequestMapping("/api")
@SessionAttributes("usuario")
public class APIController {

	@Autowired
	VehiculoService vehiculoService;

	@Autowired
	MarcaService marcaService;

	@Autowired
	ModeloService modeloService;

	@Autowired
	EmpresaService empService;

	@Autowired
	UsuarioService uService;

	@Autowired
	SuscripcionService subscripcionService;

	@Autowired
	NotificacionesService notificacionesService;

	@Autowired
	PublicacionService pubService;

	@Autowired
	Usuario usuarioLoggeado;

	@RequestMapping(value = "/marca/{idMarca}", method = RequestMethod.GET)
	public @ResponseBody
	MarcaVehiculo marcaPorId(@PathVariable Integer idMarca) {
		return marcaService.getMarcaById(idMarca);
	}

	@RequestMapping(value = "/marca/{idMarca}/modelos", method = RequestMethod.GET)
	public @ResponseBody
	List<ModeloVehiculo> modelosPorMarca(@PathVariable Integer idMarca) {
		return modeloService.getAllByMarca(idMarca);
	}

	@RequestMapping(value = "/empresa/{idEmpresa}", method = RequestMethod.GET)
	public @ResponseBody
	Boolean registrarUsuario(@PathVariable Integer idEmpresa, Usuario u) {
		NotificacionesFactory factory = new NotificacionesFactory();
		notificacionesService.guardarNotificacion(factory
				.crearNotificacionPedirTrabajo(
						empService.getEmpresaById(idEmpresa),
						uService.getUsuarioAdminEmpresa(idEmpresa), u));
		return true;
	}

	@RequestMapping(value = "/empresa/{idEmpresa}/empleado", method = RequestMethod.DELETE)
	public @ResponseBody
	Boolean borrarUsuario(@PathVariable Integer idEmpresa, Usuario u) {
		u.setIdEmpresa(null);
		uService.saveUsuario(u);
		return true;
	}

	@RequestMapping(value = "/empresa/{idEmpresa}/empleado/{idEmpleado}", method = RequestMethod.GET)
	public @ResponseBody
	Boolean registrarUsuario(@PathVariable Integer idEmpresa,
			@PathVariable Integer idEmpleado, Usuario user) {
		Usuario u = uService.getUsuarioById(idEmpleado);
		if (idEmpresa == user.getIdEmpresa()
				&& user.getIdProducto() == Producto.enterprise) {
			u.setIdEmpresa(idEmpresa);
			uService.saveUsuario(u);

			NotificacionesFactory factory = new NotificacionesFactory();
			notificacionesService.guardarNotificacion(factory
					.crearNotificacionContrato(
							empService.getEmpresaById(idEmpresa), u));
			return true;
		}
		return false;
	}

	@RequestMapping(value = "/empresa/{idEmpresa}/empleado/{idEmpleado}", method = RequestMethod.DELETE)
	public @ResponseBody
	Boolean echarUsuario(@PathVariable Integer idEmpresa,
			@PathVariable Integer idEmpleado, Usuario user) {
		Usuario u = uService.getUsuarioById(idEmpleado);
		if (u.getIdEmpresa() == idEmpresa && idEmpresa == user.getIdEmpresa()
				&& user.getIdProducto() == Producto.enterprise) {
			u.setIdEmpresa(null);
			uService.saveUsuario(u);

			NotificacionesFactory factory = new NotificacionesFactory();
			notificacionesService.guardarNotificacion(factory
					.crearNotificacionDespido(
							empService.getEmpresaById(idEmpresa), u));
			return true;
		}
		return false;
	}

	@RequestMapping(value = "/empresa/{idEmpresa}/usuarios", method = RequestMethod.GET)
	public @ResponseBody
	List<Usuario> getUsuarios(@PathVariable Integer idEmpresa) {
		return uService.getUsuariosByEmpresa(idEmpresa);
	}

	@RequestMapping(value = "/notificaciones/{idUsuario}", method = RequestMethod.GET)
	public @ResponseBody
	List<NotificacionStandard> getNotificaciones(@PathVariable Integer idUsuario) {
		List<NotificacionStandard> nots = notificacionesService
				.getNotificacionesDelUsuario(idUsuario);
		Iterator<NotificacionStandard> it = nots.iterator();
		while (it.hasNext()) {
			if (it.next().isOculta())
				it.remove();
		}
		return nots;
	}

	@RequestMapping(value = "/notificaciones/{idUsuario}/{idNotificacion}", method = RequestMethod.DELETE)
	public @ResponseBody
	Boolean deleteNotificaciones(@PathVariable Integer idUsuario,
			@PathVariable Integer idNotificacion, Usuario usuario) {
		NotificacionStandard nS = notificacionesService
				.getNotificacionById(idNotificacion);
		if (nS.getUsuario() == idUsuario && idUsuario == usuario.getId()
				&& nS.getTipo() == NotificacionStandard.SIMPLE) {
			notificacionesService.deleteNotificacion(nS);
		} else if (nS.getTipo() == NotificacionStandard.MENSAJE
				|| nS.getTipo() == NotificacionStandard.COMENTARIO_PERFIL) {
			nS.setOculta(true);
			notificacionesService.guardarNotificacion(nS);
		}
		return true;
	}

	@RequestMapping(value = "/publicacion/{idPublicacion}", method = RequestMethod.DELETE)
	public @ResponseBody
	Boolean borrarPublicacion(@PathVariable Integer idPublicacion, Usuario u) {
		Publicacion p = pubService.obtenerPorID(idPublicacion);
		if (p.getUsuario() == u.getId()) {

			List<Suscripcion> misSus = subscripcionService
					.selectByPublicacion(idPublicacion);

			for (Suscripcion suscripcion : misSus) {
				NotificacionesFactory factory = new NotificacionesFactory();
				notificacionesService.guardarNotificacion(factory
						.crearNotificacionDeCancelacionDeViaje(p,
								suscripcion.getIdSolicitante()));
				subscripcionService.delete(suscripcion);
			}

			pubService.borrar(p);
			return true;
		}
		return false;
	}

	@RequestMapping(value = "/usuario/{idUsuario}/puntos/sumar", method = RequestMethod.GET)
	public @ResponseBody
	boolean sumarPuntos(@PathVariable Integer idUsuario) {
		Usuario u = uService.getUsuarioById(idUsuario);
		u.setCalificacion(u.getCalificacion() + 1);
		uService.saveUsuario(u);
		return true;
	}

	@RequestMapping(value = "/usuario/{idUsuario}/puntos/restar", method = RequestMethod.GET)
	public @ResponseBody
	boolean restarPuntos(@PathVariable Integer idUsuario) {
		Usuario u = uService.getUsuarioById(idUsuario);
		u.setCalificacion(u.getCalificacion() - 1);
		uService.saveUsuario(u);
		return true;
	}

}
